{C++} COM 组件多层聚合嵌套原理 您所在的位置:网站首页 vue 多层组件嵌套 {C++} COM 组件多层聚合嵌套原理

{C++} COM 组件多层聚合嵌套原理

#{C++} COM 组件多层聚合嵌套原理| 来源: 网络整理| 查看: 265

 这个小Demo是控制台调用三个动态链接库的,每个链接库中都有一个方法,最外面的库CompB.dll里面是减法运算, 

 聚合CompC.dll里面的乘法,CompC.dll聚合CompA.dll里面的加法。CompB.dll调用接口是OtherInterface,CompC.dll

调用接口是AnyInterface,CompA.dll调用接口是SomeInterface。 CompB内部指针Inner指向CompC,CompC内部指针 

Inner指向CompA,Outer指针指向CompB,CompA内部指针Outer指针指向CompC,通过这四个指针,可以使接口查询

双向传递。也就是说我可以通过OtherInterface拿到CompA的Add方法,也可以通过SomeInterface拿到CompB的Minus

方法,调用方式非常灵活。三个接口无论调用哪一个都可以访问到三个动态链接库中的所有方法。每一个方法都可以通过不同

接口调用,原理也很清晰和简单。多层聚合调用的中间层dll就需要一对指针指向上层dll和下层dll,就像CompC一样。实现也不

复杂,每个动态链接库都有一个查询接口方法,CompC和CompA通过非委托查询接口,进行调用传递。初始化过程是这样的,

CompB初始化CompC实例,CompC初始化CompA实例。CompB如果希望调用CompA就必须先初始化CompC,初始化过

程也很清晰。为了模块的灵活性,多写些代码还是值得滴。

基本原理如图:

 

我本地的执行输出: 

 

 

 

多层聚合嵌套核心方法是CompC的两个查询方法:

QueryInterface: 

复制代码  1 HRESULT CC::QueryInterface(const IID& iid, void **ppv) 2 { 3     printf("---------------------excute CompC QueryInterface!!!\n"); 4     if ( iid == IID_OtherInterface )  5     { 6         if(m_pUnknownOuter != NULL){ 7             printf("CompC m_pUnknownOuter is not null!\n"); 8             return m_pUnknownOuter->QueryInterface(iid, ppv); 9         }else{10             return NondelegationQueryInterface(iid, ppv);11         }12     }13     if ( iid == IID_SomeInterface ) {14         if  ( m_pUnknownInner != NULL ){15             printf("CompC m_pUnknownInner is not null!\n");16             return m_pUnknownInner->QueryInterface(iid, ppv);17         } else{18             return NondelegationQueryInterface(iid, ppv);19         }20     } else {21         return NondelegationQueryInterface(iid, ppv);22     }23 } 复制代码

 

 NondelegationQueryInterface:

 

复制代码  1 HRESULT CC::NondelegationQueryInterface(const IID& iid, void **ppv) 2 { 3     printf("---------------------excute CompC NondelegationQueryInterface!!!\n"); 4     if ( iid == IID_IUnknown ) 5     { 6         *ppv = (INondelegatingUnknown *) this ; 7         ((IUnknown *)(*ppv))->AddRef() ; 8     } else if ( iid == IID_AnyInterface )  9     {10         *ppv = (IAnyInterface *) this ;11         ((IAnyInterface *)(*ppv))->AddRef() ;12     } else if ( iid == IID_SomeInterface ) 13     {14         return m_pUnknownInner->QueryInterface(iid, ppv) ;15     } else if ( iid == IID_OtherInterface ) 16     {17         return m_pUnknownOuter->QueryInterface(iid, ppv) ;18     } else19     {20         *ppv = NULL;21         return E_NOINTERFACE ;22     }23     return S_OK;24 } 复制代码

 本文转自施杨博客园博客,原文链接:http://www.cnblogs.com/shiyangxt/archive/2010/12/04/1896398.html,如需转载请自行联系原作者



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有